﻿#include "texture2d.h"

CTexture2D::CTexture2D()
{
	m_uiTextrueID=0;
	m_ShaderProgram=0;
	m_VertexShader=0;
	m_FragmentShader=0;
	m_uiImgW=0;
	m_uiImgH=0;
	m_uiImgPotW=0;
	m_uiImgPotH=0;
}

CTexture2D::~CTexture2D()
{
}

bool CTexture2D::LoadPng(const char* path,bool bKeepAlpha)
{
	m_bKeepAlpha=bKeepAlpha;
	m_vAlpha.clear();
	std::vector<unsigned char> image;
	unsigned int png_error = LodePNG::decode(image, m_uiImgW, m_uiImgH, path);
	if(0!=png_error)
	{
		printf("load png failed:%d\n",png_error);
		return false;
	}

	//optimize later: split img
	while(m_uiImgPotW < m_uiImgW)
	{
		m_uiImgPotW <<= 1;
	}
	while(m_uiImgPotH < m_uiImgH)
	{
		m_uiImgPotH <<= 1;
	}
	unsigned char* m_pData = new unsigned char[m_uiImgPotW * m_uiImgPotH * 4];
	memset(m_pData,0,sizeof(unsigned char) * m_uiImgPotW * m_uiImgPotH * 4);

	//pixels
	if(bKeepAlpha)
	{
		unsigned int iSize=image.size();
		m_vAlpha.resize(iSize);
		for(unsigned int i = 0;i < iSize;i ++)
		{
			m_vAlpha[i]=0!=image[i]?true:false;
		}
	}

	for(unsigned int i = 0;i < m_uiImgH;i ++)
	{
		memcpy(&m_pData[i*m_uiImgPotW*4],&image[i*m_uiImgW*4],m_uiImgW*4);
	}

	image.clear();

	//glEnable(GL_TEXTURE_2D);
	glGenTextures(1, &m_uiTextrueID);
	glBindTexture(GL_TEXTURE_2D, m_uiTextrueID);

	glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
	glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
	glTexParameterf( GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE );
	glTexParameterf( GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE );

	glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, m_uiImgPotW, m_uiImgPotH, 0, GL_RGBA, GL_UNSIGNED_BYTE, m_pData);

	glBindTexture(GL_TEXTURE_2D, 0);

	if(NULL != m_pData)
	{
		delete [] m_pData;
		m_pData = NULL;
	}
	return true;
}

bool CTexture2D::LoadShaderSource(const char* vs,const char* fs)
{
	if(!LoadVshSource(vs))
	{
		return false;
	}
	if(!LoadFshSource(fs))
	{
		return false;
	}

	m_ShaderProgram=glCreateProgram();
	glAttachShader(m_ShaderProgram,m_VertexShader);
	glAttachShader(m_ShaderProgram,m_FragmentShader);

	glBindAttribLocation(m_ShaderProgram,m_vertexLoc,"");

	glLinkProgram(m_ShaderProgram);
	return true;
}

bool CTexture2D::LoadVshSource(const char* source)
{
	FILE *pFile=fopen(source,"r");
	if(NULL==pFile)
	{
		printf("load file: %s error\n",source);
		return false;
	}
	fseek(pFile,0,SEEK_END);
	long fileLen=ftell(pFile);
	fseek(pFile,0,SEEK_SET);
	char* szSource=new char[fileLen];
	fread(szSource,fileLen,1,pFile);

	delete [] szSource;
	fclose(pFile);


	GLint compiled;
	// Create the shader object
	m_VertexShader = glCreateShader(GL_VERTEX_SHADER);
	if(0==m_VertexShader)
	{
		return false;
	}
	// Load the shader source
	glShaderSource(m_VertexShader, 1, &source, NULL);
	// Compile the shader
	glCompileShader(m_VertexShader);
	// Check the compile status
	glGetShaderiv(m_VertexShader, GL_COMPILE_STATUS, &compiled);
	if(GL_FALSE == compiled)
	{
		GLint infoLen = 0;
		glGetShaderiv(m_VertexShader, GL_INFO_LOG_LENGTH, &infoLen);
		if(infoLen > 1)
		{
			char* infoLog = new char[infoLen];
			glGetShaderInfoLog(m_VertexShader, infoLen, NULL, infoLog);
			printf("Error compiling shader:\n%s\n", infoLog);
			delete [] infoLog;
		}
		glDeleteShader(m_VertexShader);
		return false;
	}
	return true;
}

bool CTexture2D::LoadVshBin(const char* bin)
{
	return true;
}

bool CTexture2D::LoadFshSource(const char* source)
{
	GLint compiled;
	m_FragmentShader=glCreateShader(GL_FRAGMENT_SHADER);
	if(0==m_FragmentShader)
	{
		return false;
	}
	glShaderSource(m_FragmentShader,1,&source,NULL);
	glCompileShader(m_FragmentShader);
	glGetShaderiv(m_FragmentShader,GL_COMPILE_STATUS,&compiled);
	if(GL_FALSE == compiled)
	{
		GLint infoLen = 0;
		glGetShaderiv(m_FragmentShader, GL_INFO_LOG_LENGTH, &infoLen);
		if(infoLen > 1)
		{
			char* infoLog = new char[infoLen];
			glGetShaderInfoLog(m_FragmentShader, infoLen, NULL, infoLog);
			printf("Error compiling shader:\n%s\n", infoLog);
			delete [] infoLog;
		}
		glDeleteShader(m_FragmentShader);
		return false;
	}
	return true;
}

bool CTexture2D::LoadFshBin(const char* bin)
{
	return true;
}

void CTexture2D::Release()
{
}

void CTexture2D::Update()
{
}

void CTexture2D::Render()
{
}

bool CTexture2D::GetAlpha(int x,int y)
{
	if(m_bKeepAlpha)
	{
	}
	return false;
}
